package edu.mercer.sse554.bkp;

import java.math.RoundingMode;
import java.text.NumberFormat;

/**
 * Execution time measurement suitable for multiple thread usage.<p>
 */

public class ConcurrTimer    
{
	private Long _startTime = 0L;
	
	private Long _endTime = 0L;

	/** thread safe number formatter used for display of time */
	
	private static final ThreadLocal<NumberFormat> _numberFormatter = 
			new ThreadLocal<NumberFormat>()
			{
				@Override
				protected NumberFormat initialValue()
				{
					NumberFormat _numFmt = NumberFormat.getNumberInstance();
					
					_numFmt.setMinimumFractionDigits(2);

					_numFmt.setMaximumFractionDigits(5);

					_numFmt.setGroupingUsed(false);

					_numFmt.setRoundingMode(RoundingMode.UNNECESSARY);

					return _numFmt;
					
				}//method
		
			};

	
	private ConcurrTimer()
	{
		super();
		
	}//constructor

	
	/**
	 * @return this - new instance
	 */
	
	public static ConcurrTimer factory()
	{
		return new ConcurrTimer();
		
	}//method
	

	/**
	 * Start the clock: record start-time for the time measurement.<p>
	 * 
	 * @return  this
	 */
	
	public ConcurrTimer start()
	{
		_startTime = System.currentTimeMillis();
		
		return this;
		
	}//method


	/**
	 * Stop the clock: record end-time for the time measurement.<p>
	 * 
	 * @return  this
	 */
	
	public ConcurrTimer stop()
	{
		_endTime = System.currentTimeMillis();

		return this;
		
	}//method
	

	/**
	 * @return Long - time elapsed in Milliseconds, -1 end time more recent 
	 * 		than start time
	 */
	
	public Long elapsed()
	{
		return ( _endTime >= _startTime ) ? ( _endTime - _startTime ) : -1L;
		
	}//method
	

	/**
	 * @return Double - time elapsed in Seconds, -1 end time not more 
	 * 		recent than start time
	 */
	
	public Double elapsedSeconds()
	{
		if( _endTime <= _startTime )
		{
			return -1D;
			
		}//if
			
		return ( new Double(_endTime) - new Double(_startTime) ) / 1000D;
		
	}//method
	
	
	/**
	 * @return String - time elapsed in seconds, formatted
	 */
	
	public String elapsedAsString()
	{		
		return _numberFormatter.get()
							   .format( elapsedSeconds() );
		
	}//method
	
		
}//class
